package com.lancoo.dictionary.activity;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.ScrollView;
import android.widget.TextView;

import com.example.library.AutoFlowLayout;
import com.example.library.FlowAdapter;
import com.github.zackratos.ultimatebar.UltimateBar;
import com.google.gson.Gson;
import com.lancoo.dictionary.DictionaryHelper;
import com.lancoo.dictionary.R;
import com.lancoo.dictionary.data.adapter.SearchHistoryAdapter;
import com.lancoo.dictionary.data.adapter.SearchResultAdapter;
import com.lancoo.dictionary.data.model.DicSearchBehavior;
import com.lancoo.dictionary.data.model.SearchHistory;
import com.lancoo.dictionary.data.model.Vocabulary;
import com.lancoo.dictionary.nc.NetworkConnectionByContent;
import com.lancoo.dictionary.utils.KeyBoardUtils;
import com.lancoo.dictionary.widget.QuickclearEditText;
import com.lancoo.dictionary.widget.QuickclearEditText.InputChangedListenner;

import org.xutils.DbManager;
import org.xutils.common.Callback.CommonCallback;
import org.xutils.common.util.DensityUtil;
import org.xutils.ex.DbException;

import java.util.Date;
import java.util.List;

/**
 * Copyright (C) 2016 LANCOO. All Rights Reserved.
 *
 * @author 刘孟孟 2016年5月17日
 */
public class DictionaryActicity extends AppCompatActivity implements InputChangedListenner, CommonCallback<String>,
        OnPreparedListener, OnItemClickListener, OnKeyListener,MediaPlayer.OnCompletionListener {

    public static final String KEY_PRECONTENT = "preContent";
    public static final String KEY_API_PATH = "apiPath";
    public static final String KEY_RES_BASEURL = "resBaseUrl";
    public static final String KEY_SHOW_BACK_BTN = "showBackBtn";

    private QuickclearEditText searchBox;
    private TextView searchCommand;
    private ListView searchHistoryLv;
    private LinearLayout searchHistoryLl;
    private TextView searchHistoryClearLv;
    private RecyclerView searchResultRv;

    private DbManager dbManager;
    private Vocabulary vocabulary;
    private MediaPlayer mediaPlayer;
    private SearchResultAdapter searchResultAdapter;
    private SearchHistoryAdapter searchHistoryAdapter;

    private ProgressBar progressBar;
    private CardView dicNoticeCv;
    private TextView dicNotice;

    private NetworkConnectionByContent curConnection;
    protected Toolbar mToolbar;
    protected AutoFlowLayout autoFlowLayout;
    protected ScrollView scrollView;
    protected TextView tv_tag;

    public void onClick(View v) {
        if (v.getId() == R.id.dic_search_command) {
            if (getString(R.string.lcdic_cancel).equals(searchCommand.getText())) {
                finish();
            } else {
                goSearch();
            }
        } else if (v.getId() == R.id.dic_back_btn) {
            finish();
        } else if (v.getId() == R.id.tv_history_clear) {
            View inflate = LayoutInflater.from(this).inflate(R.layout.lcdic_dialog_train_pause, null);
            AlertDialog.Builder builder = new AlertDialog.Builder(DictionaryActicity.this,R.style.LcDicNoBgColorStyle);
            builder.setView(inflate);
            final AlertDialog alertDialog = builder.create();
            alertDialog.show();
            WindowManager.LayoutParams attributes = alertDialog.getWindow().getAttributes();
            attributes.width= DensityUtil.dip2px(270);
            alertDialog.getWindow().setAttributes(attributes);
            inflate.findViewById(R.id.tv_dialog_cancel).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    alertDialog.dismiss();
                }
            });
            inflate.findViewById(R.id.tv_dialog_confirm).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    alertDialog.dismiss();
                    if (dbManager != null) {
                        try {
                            dbManager.delete(SearchHistory.class);
                            loadSearchHistories(null);
                        } catch (DbException e) {
                            e.printStackTrace();
                        }
                    }
                }
            });
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
        if (savedInstanceState != null) {
            DictionaryHelper.API_PATH = savedInstanceState.getString(KEY_API_PATH);
            DictionaryHelper.RES_BASE_URL = savedInstanceState.getString(KEY_RES_BASEURL);
            DictionaryHelper.SHOW_BACK_BTN = savedInstanceState.getBoolean(KEY_SHOW_BACK_BTN);
        }
        setContentView(R.layout.lcdic_activty_dictionary);
        UltimateBar.Companion.with(this).applyNavigation(false).create().transparentBar();
        findViewById(R.id.dic_back_btn).setVisibility(DictionaryHelper.SHOW_BACK_BTN ? View.VISIBLE : View.GONE);
        autoFlowLayout = findViewById(R.id.afl_word);
        scrollView = findViewById(R.id.scrollview);
        tv_tag = findViewById(R.id.search_tag);
        searchHistoryLl =  findViewById(R.id.dic_search_history_ll);
        searchHistoryClearLv = (TextView) findViewById(R.id.tv_history_clear);
        searchBox = (QuickclearEditText) findViewById(R.id.dic_search_box);
        searchCommand = (TextView) findViewById(R.id.dic_search_command);
        searchHistoryLv = (ListView) findViewById(R.id.dic_search_history);
        searchResultRv = (RecyclerView) findViewById(R.id.dic_search_result_rv);
        progressBar = (ProgressBar) findViewById(R.id.dic_progressbar);
        dicNoticeCv = (CardView) findViewById(R.id.dic_notice_cv);
        dicNotice = (TextView) findViewById(R.id.dic_notice);
        searchHistoryLv.setOnItemClickListener(this);
        searchBox.setOnKeyListener(this);
        searchBox.setInputChangedListenner(this);
        mediaPlayer = new MediaPlayer();
        mediaPlayer.setOnPreparedListener(this);
        mediaPlayer.setOnCompletionListener(this);
        dbManager = DictionaryHelper.getDbManager();
        initToolbar();

        Intent intent = getIntent();
        String preContent = intent.getStringExtra(KEY_PRECONTENT);
        if (TextUtils.isEmpty(preContent)) {
            loadSearchHistories(null);
        } else {
            try {
                autoSearch(preContent);
            } catch (DbException e) {
                e.printStackTrace();
            }
        }
    }
    List<SearchHistory> searchHistories = null;
    private void loadSearchHistories(CharSequence input) {
        if (dbManager == null) {
            searchHistoryLl.setVisibility(View.GONE);
            return;
        }
        searchHistoryLl.setVisibility(View.VISIBLE);
        if (TextUtils.isEmpty(input)) {
            try {
                searchHistories = dbManager.selector(SearchHistory.class).orderBy("searchDate", true).findAll();
            } catch (DbException e) {
                e.printStackTrace();
            }
        } else {
            try {
                searchHistories = dbManager.selector(SearchHistory.class).where("searchContent", "LIKE", input + "%")
                        .findAll();
            } catch (DbException e) {
                e.printStackTrace();
            }
        }
        if (searchHistories == null) {
            return;
        }

        if (searchHistories.size() < 1) {
            searchHistoryClearLv.setVisibility(View.GONE);
        } else {
            searchHistoryClearLv.setVisibility(View.VISIBLE);
        }
        scrollView.setVisibility(searchHistories.size() < 1?View.GONE:View.VISIBLE);
        tv_tag.setText(searchHistories.size() < 1?R.string.lcdic_search_no_history:R.string.lcdic_search_history);
//        if (searchHistoryAdapter == null) {
//            searchHistoryAdapter = new SearchHistoryAdapter(searchHistories);
//            searchHistoryLv.setAdapter(searchHistoryAdapter);
//        } else {
//            searchHistoryAdapter.updateDataSet(searchHistories);
//        }
        autoFlowLayout.clearViews();
        autoFlowLayout.setAdapter(new FlowAdapter(searchHistories) {
            @Override
            public View getView(int i) {
                String key = searchHistories.get(i).getSearchContent();
                View inflate = LayoutInflater.from(DictionaryActicity.this).inflate(R.layout.lcdic_list_item_word_study_second, null);
                TextView itemView = (TextView)inflate.findViewById(R.id.tv_word);
                itemView.setText(key);
                return inflate;
            }
        });

        autoFlowLayout.setOnItemClickListener(new AutoFlowLayout.OnItemClickListener() {
            @Override
            public void onItemClick(int position, View view) {
                SearchHistory searchHistory = searchHistories.get(position);
                String searchContent = searchHistory.getSearchContent();
                searchBox.setText(searchContent);
                searchBox.setSelection(searchContent.length());
                showSearchResultFromDB();
            }
        });
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        outState.putString(KEY_API_PATH, DictionaryHelper.API_PATH);
        outState.putString(KEY_RES_BASEURL, DictionaryHelper.RES_BASE_URL);
        outState.putBoolean(KEY_SHOW_BACK_BTN, DictionaryHelper.SHOW_BACK_BTN);
        super.onSaveInstanceState(outState);
    }

    /**
     * InputChangedListenner from QuickclearEditText
     */
    @Override
    public void onInputChanged(boolean hasInput, CharSequence input) {
        searchCommand.setText(hasInput ? R.string.lcdic_search : R.string.lcdic_cancel);
        if (curConnection != null) {
            curConnection.cancelConnection();
        }
        dicNoticeCv.setVisibility(View.GONE);
        searchResultRv.setVisibility(View.GONE);
        progressBar.setVisibility(View.GONE);
        searchHistoryLl.setVisibility(View.VISIBLE);
        searchHistoryLv.setVisibility(View.VISIBLE);
        loadSearchHistories(input);
    }

    /**
     * networkConnection callback region
     */
    @Override
    public void onSuccess(String result) {
        vocabulary = new Gson().fromJson(result, Vocabulary.class);
        try {
            if (vocabulary != null) {
                if (dbManager != null) {
                    dbManager.saveOrUpdate(new SearchHistory(vocabulary.getCwName(), new Date(), result));
                }
            }
        } catch (DbException e) {
            e.printStackTrace();
        }
        showSearchResult();
    }

    @Override
    public void onError(Throwable ex, boolean isOnCallback) {
        showNotice(R.string.lcdic_search_failed);
    }

    @Override
    public void onCancelled(CancelledException cex) {
    }

    @Override
    public void onFinished() {
        progressBar.setVisibility(View.GONE);
        DictionaryHelper.sendDicSearchBroadcast(this, searchBox.getRealInput(), DicSearchBehavior.SOURCE_HTTP, vocabulary != null && vocabulary.getCwName().equals(searchBox.getRealInput()));
    }

    /**
     * networkConnection callback region
     */

    private void goSearch() {
        KeyBoardUtils.closeKeybord(this);
        dicNoticeCv.setVisibility(View.GONE);
        searchHistoryLl.setVisibility(View.GONE);
        searchHistoryLv.setVisibility(View.GONE);
        searchResultRv.setVisibility(View.GONE);
        progressBar.setVisibility(View.VISIBLE);
        String knowlegde = searchBox.getRealInput();
        curConnection = new NetworkConnectionByContent(knowlegde, this);
    }

    private void showSearchResult() {
        if (vocabulary == null) {
            showNotice(R.string.lcdic_search_failed);
            return;
        }
        searchResultRv.setVisibility(View.VISIBLE);
        if (searchResultAdapter == null) {
            searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
            searchResultRv.setAdapter(searchResultAdapter);
        } else {
            searchResultRv.smoothScrollToPosition(0);
            searchResultAdapter.updateData(vocabulary);
        }
    }

    private void showSearchResultFromDB() {
        KeyBoardUtils.closeKeybord(this);
        dicNoticeCv.setVisibility(View.GONE);
        progressBar.setVisibility(View.GONE);
        searchHistoryLv.setVisibility(View.GONE);
        searchHistoryLl.setVisibility(View.GONE);
        String knowlegde = searchBox.getRealInput();
        try {
            SearchHistory searchHistory = dbManager.findById(SearchHistory.class, knowlegde);
            vocabulary = new Gson().fromJson(searchHistory.getMeaning(), Vocabulary.class);
            searchResultRv.setVisibility(View.VISIBLE);
            if (searchResultAdapter == null) {
                searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
                searchResultRv.setAdapter(searchResultAdapter);
            } else {
                searchResultRv.smoothScrollToPosition(0);
                searchResultAdapter.updateData(vocabulary);
            }
        } catch (DbException e) {
            e.printStackTrace();
        } finally {
            if (vocabulary == null) return;
            DictionaryHelper.sendDicSearchBroadcast(this, vocabulary.getCwName(), DicSearchBehavior.SOURCE_DB, true);
        }
    }

    private void autoSearch(String searchContent) throws DbException {
        searchBox.setText(searchContent);
        searchBox.setSelection(searchContent.length());
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN
                | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_UNSPECIFIED);
        dicNoticeCv.setVisibility(View.GONE);
        searchHistoryLv.setVisibility(View.GONE);
        searchHistoryLl.setVisibility(View.GONE);
        String knowlegde = searchBox.getRealInput();
        SearchHistory searchHistory = dbManager == null ? null : dbManager.findById(SearchHistory.class, knowlegde);
        if (searchHistory != null) {
            progressBar.setVisibility(View.GONE);
            searchResultRv.setVisibility(View.VISIBLE);
            vocabulary = new Gson().fromJson(searchHistory.getMeaning(), Vocabulary.class);
            if (searchResultAdapter == null) {
                searchResultAdapter = new SearchResultAdapter(vocabulary, mediaPlayer);
                searchResultRv.setAdapter(searchResultAdapter);
            } else {
                searchResultRv.smoothScrollToPosition(0);
                searchResultAdapter.updateData(vocabulary);
            }
            DictionaryHelper.sendDicSearchBroadcast(this, vocabulary.getCwName(), DicSearchBehavior.SOURCE_DB, true);
        } else {
            progressBar.setVisibility(View.VISIBLE);
            searchResultRv.setVisibility(View.GONE);
            curConnection = new NetworkConnectionByContent(knowlegde, this);
        }
    }

    private void showNotice(String notice) {
        dicNoticeCv.setVisibility(View.VISIBLE);
        dicNotice.setText(notice);
    }

    private void showNotice(int noticeResId) {
        dicNoticeCv.setVisibility(View.VISIBLE);
        dicNotice.setText(noticeResId);
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.release();
            mediaPlayer = null;
        }
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        mp.start();
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        SearchHistory searchHistory = (SearchHistory) parent.getItemAtPosition(position);
        String searchContent = searchHistory.getSearchContent();
        searchBox.setText(searchContent);
        searchBox.setSelection(searchContent.length());
        showSearchResultFromDB();

    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_ENTER) {
            if (searchBox.getRealInput().length() > 0) {
                goSearch();
            }
            return true;
        }
        return false;
    }

    public static void startWithContent(Context context, String preContent) {
        Intent intent = new Intent(context, DictionaryActicity.class);
        intent.putExtra(KEY_PRECONTENT, preContent);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(intent);
    }

    public void initToolbar(){
        mToolbar = (Toolbar)findViewById(R.id.toolbar);
        if(mToolbar ==null){
            mToolbar =(Toolbar)findViewById(R.id.toolbar);
        }
        mToolbar.setTitle("");
        setSupportActionBar(mToolbar);
        mToolbar.setBackgroundResource(R.drawable.lcdic_shape_head_bg);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeAsUpIndicator(R.mipmap.lcdic_icon_back);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.JELLY_BEAN){
            mToolbar.setPadding(0, getTopPadding(),0, mToolbar.getPaddingBottom());//-ToolsUtils.dip2px(this,15)
        }
        LinearLayout layout_search = (LinearLayout) findViewById(R.id.layout_search);
        if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.JELLY_BEAN){
            layout_search.setPadding(dip2px(this,50), getTopPadding()/2,0,0);
            ViewGroup.LayoutParams layoutParams = layout_search.getLayoutParams();
            layoutParams.height=dip2px(this,28)+ getTopPadding()/2 ;
            layout_search.setLayoutParams(layoutParams);
        }

    }

    public int  getTopPadding(){
        return mToolbar.getPaddingTop()+getStatusHeight(this)-dip2px(this,5);
    }


    /**
     * 获得状态栏的高度
     *
     * @param context
     * @return
     */
    public int getStatusHeight(Context context) {

        int statusHeight = -1;
        try {
            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
            Object object = clazz.newInstance();
            int height =
                    Integer.parseInt(clazz.getField("status_bar_height").get(object).toString());
            statusHeight = context.getResources().getDimensionPixelSize(height);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return statusHeight;
    }

    //dp转px
    public int dip2px(Context context, float dpValue) {
        final float scale = context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if(item.getItemId()==android.R.id.home){
            finish();
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        if(searchResultAdapter!=null){
            searchResultAdapter.resetPlayState();
        }
    }
}
